﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows;

using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Windows.Controls;
using Newtonsoft.Json;

using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Configuration;

using System.ComponentModel;
using System.Collections.ObjectModel;
using WpfApp1.Models;
using WpfApp1.Services;
using DevExpress.Mvvm;
using Gardener.Common;
using System.Windows.Input;

//正则表达式的名称空间
using System.Text.RegularExpressions;

namespace WpfApp1.ViewModels
{
    public partial class MainViewModel : ViewModelBase, INotifyPropertyChanged
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public MainViewModel()
        {
            httpClient.BaseAddress = new Uri("https://localhost:44320");
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
            Name = "1000";
            
            Directory_Load();
            //生成内存目录树的方法
            CreateItemTree();
            SearchCommand = new DelegateCommand<object>(SearchCommandExcute);
            LoginCommand = new DelegateCommand(LoginCommandExcute);
            //以下命令已转移至MainWindowService
            //AddfileCommand = new DelegateCommand<object>(AddfileCommandExcute);
            InitfolderCommand = new DelegateCommand(InitfolderCommandExcute);
            HandleparaCommand = new DelegateCommand<object>(HandleparaCommandExcute);
            SychronizeToserverCommand = new DelegateCommand(SynchronizeToserverExcute);

            AddFolderServerCommand = new DelegateCommand(AddFolderServerExcute);
            GetFileItemsFromSerCommand = new DelegateCommand(GetFileItemsFromSerExcute);

        }
        //网络对象的实现
        HttpClient httpClient = new HttpClient();

        /// <summary>
        /// 测试命令的执行函数
        /// </summary>
        /// <param name="obj"></param>
        private void SearchCommandExcute(object obj)
        {
            string a = obj as string;
            MessageBox.Show(a);

        }
        /// <summary>
        /// 添加文件时的执行函数，执行函数已经转移至MainWindowService.cs
        /// </summary>
        /// <param name="obj"></param>

        //private async void AddfileCommandExcute(object obj)
        //{
        //    string ConfigPath_Docu = System.IO.Path.GetTempPath() + @"CRDCCollaboPlatConfig\Revit\DocumentInfo.CRDC";

        //    //根目录文件的长度
        //    int temp = ConfigurationManager.AppSettings["RootPath"].Length;
        //    //剔除根目录
        //    string source = (obj as string).Substring(temp);
        //    //对路径进行编码 
        //    source = PasswordGenerate.PathEncode(source);
        //    MessageBox.Show(source);

        //    //拿到用户的配置参数
        //    string UserId = ConfigService.GetSettingString("UserId");
        //    //查看用户的权限
        //    string url = $"/api/file/check-user-source-auth/{UserId}/{source}";
        //    var respone = await httpClient.GetAsync($"/api/file/check-user-source-auth/{UserId}/{source}");
        //    respone.EnsureSuccessStatusCode();
        //    var product = await respone.Content.ReadFromJsonAsync<ApiResult<string>>();
        //    string authResult = product.Data;
        //    if (authResult == "1" || authResult=="2")//说明有权力增加页面  1 所有 2 所属 3普通
        //    {
        //        string newFile = System.IO.Path.Combine((obj as string), "新增文件.rfa");
        //        string newFile_encode = PasswordGenerate.PathEncode(newFile);
        //        string url_newFile = $"/api/file/file/{UserId}/{newFile_encode}/{newFile_encode}";
        //        var respone_newFile = await httpClient.GetAsync(url_newFile);
        //        respone_newFile.EnsureSuccessStatusCode();
        //        var product_newFile = await respone_newFile.Content.ReadFromJsonAsync<ApiResult<DocumentDto>>();
        //        DocumentDto result = product_newFile.Data;
        //        if (result != null)//说明数据库端添加成功
        //        {
        //            //拿到字典的键值对
        //            Dictionary<string, string> keyValuePairs_Docu = ConfigService.DictFromFile(ConfigPath_Docu);
        //            keyValuePairs_Docu.Add(result.StrGuid, PasswordGenerate.PathDecode(result.DocumentPath));
        //            //存入本地数据库中
        //            ConfigService.DictToFile(keyValuePairs_Docu, ConfigPath_Docu);
        //            File.Create(newFile);
        //        }
        //    }
        //    else
        //    {
        //        MessageBox.Show("您无权新增文件");
        //    }
        //}

        //在服务器端添加文件夹
        private async void AddFolderServerExcute()
        {

        }

        //从服务器端拿到目录树结构
        private async void GetFileItemsFromSerExcute()
        {
            //内存状态下的目录树,初始化
            FileItemsData =  new List<Item>();

            MessageBox.Show("sss");
            //首先请求文件夹信息
            string username = "admin";
            string url_folder = $"/api/file/request-file-dir/{username}";
            var respone_folder = await httpClient.GetAsync(url_folder);
            respone_folder.EnsureSuccessStatusCode();
            var product_folder = await respone_folder.Content.ReadFromJsonAsync<ApiResult<List<SourceDto>>>();
            List<SourceDto> sourceDtos = product_folder.Data;
            foreach(SourceDto sourceDto in sourceDtos)
            {
                //声明单个项目
                var item = new Item { Id = sourceDto.StrGuid, ParentID = sourceDto.ParentId, DisplayText = sourceDto.SourceName };
                //将单个项目添加到列表中
                FileItemsData.Add(item);

            }
            // 更新上下文
            FileItems = TreeHelper.CreateTree<Item>(FileItemsData, item => item.Id, item => item.ParentID);

            //其次在更新文件 


        }
        /// <summary>
        /// 登陆命令的执行函数
        /// </summary>
        private async void LoginCommandExcute()
        {
            try
            {
                int UserId = 0;
                LoginInput loginInput = new LoginInput { Account = UserName, Password = Password };
                var response = await httpClient.PostAsJsonAsync<LoginInput>("/api/rbac/login", loginInput);
                response.EnsureSuccessStatusCode();
                var products = await response.Content.ReadFromJsonAsync<ApiResult<LoginOutput>>();
                //临时存储用户名的ID
                UserId = products.Data.Id;
                //将用户信息写入到配置文件中
                ConfigService.UpdateSettingString("User", products.Data.Account);
                //用户的ID号码
                ConfigService.UpdateSettingString("UserId", products.Data.Id.ToString());
                ConfigService.UpdateSettingString("MajorID", products.Data.MajorID.ToString());

                //下面开始进行所属及所有文件夹的收集
                //所属文件夹,将用户的所属文件夹
                string ConfigPath_FolderBelonged = System.IO.Path.GetTempPath() + @"CRDCCollaboPlatConfig\Revit\FolderBelonged.CRDC";
                string ConfigPath_FolderOwned = System.IO.Path.GetTempPath() + @"CRDCCollaboPlatConfig\Revit\FolderOwned.CRDC";
                var response_belonged = await httpClient.GetAsync($"/api/file/folder-belonged/{UserId}");
                response_belonged.EnsureSuccessStatusCode();
                var products_belonged = await response_belonged.Content.ReadFromJsonAsync<ApiResult<List<SourceDto>>>();
                List<SourceDto> sourceDtos_belonged = products_belonged.Data;
                //将所属文件夹写入到本地缓存中
                Dictionary<string, string> keyValuePairs_belonged = new Dictionary<string, string>();
                if(sourceDtos_belonged != null)  //首先判断是否为空
                {
                    foreach (SourceDto sourceDto in sourceDtos_belonged)
                    {
                        keyValuePairs_belonged.Add(sourceDto.StrGuid,PasswordGenerate.PathDecode(sourceDto.SourcePath));
                    }
                }
                
                //进行硬盘操作
                ConfigService.DictToFile(keyValuePairs_belonged, ConfigPath_FolderBelonged);

                //用户所有的文件夹 进行下面的操作
                var response_owned = await httpClient.GetAsync($"/api/file/folder-owned/{UserId}");
                response_owned.EnsureSuccessStatusCode();
                var products_owned = await response_owned.Content.ReadFromJsonAsync<ApiResult<List<SourceDto>>>();
                List<SourceDto> sourceDtos_owned = products_owned.Data;
                //将用户所拥有的文件夹写入到本地缓存中
                Dictionary<string, string> keyValuePairs_owned = new Dictionary<string, string>();
                if (sourceDtos_owned != null) //首先判断是否为空
                {
                    foreach (SourceDto sourceDto in sourceDtos_owned)
                    {
                        keyValuePairs_owned.Add(sourceDto.StrGuid, PasswordGenerate.PathDecode(sourceDto.SourcePath));
                    }
                }
                
                //进行硬盘操作
                ConfigService.DictToFile(keyValuePairs_owned, ConfigPath_FolderOwned);

                MessageBox.Show(ConfigService.GetSettingString("User") + "登陆成功");
            }
            catch (Newtonsoft.Json.JsonException jex)
            {
                MessageBox.Show(jex.ToString());
            }
            catch (HttpRequestException ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {

            }

        }
        /// <summary>
        /// 初始化文件夹命令的执行函数
        /// </summary>
        private async void InitfolderCommandExcute()
        {
            //*********************    上一版本的保存    *************************//
            ////配置文件保存的目录
            //string ConfigPath_Folder = System.IO.Path.GetTempPath() + @"CRDCCollaboPlatConfig\Revit\FolderInfo.CRDC";
            //string ConfigPath_Docu = System.IO.Path.GetTempPath() + @"CRDCCollaboPlatConfig\Revit\DocumentInfo.CRDC";

            ////文件保存路径
            //string rootpath = ConfigurationManager.AppSettings["RootPath"];

            //var respone = await httpClient.GetAsync("/api/file/request-file-dir/sss");
            //respone.EnsureSuccessStatusCode();
            //var product = await respone.Content.ReadFromJsonAsync<ApiResult<List<SourceDto>>>();

            ////初始化文件夹
            ////资源中的相关文件夹的数组
            //List<SourceDto> sourceDtos = product.Data;
            //List<string> folders = new List<string>();
            ////拿到当前的目录文件
            //Dictionary<string, string> keyValuePairs_Source = ConfigService.DictFromFile(ConfigPath_Folder);

            //if (keyValuePairs_Source == null)  //表示是第一次存储
            //{
            //    keyValuePairs_Source = new Dictionary<string, string>();
            //    foreach (SourceDto sourceDto in sourceDtos)
            //    {
            //        string pathServer = System.IO.Path.Combine(rootpath, PasswordGenerate.PathDecode(sourceDto.SourcePath));
            //        //先创建目录
            //        System.IO.Directory.CreateDirectory(pathServer);
            //        //再将目录存储到字典中
            //        keyValuePairs_Source.Add(sourceDto.StrGuid, PasswordGenerate.PathDecode(sourceDto.SourcePath));

            //    }
            //    //将字典存入到配置文件
            //    ConfigService.DictToFile(keyValuePairs_Source, ConfigPath_Folder);
            //}
            //else  //不是第一次存储
            //{
            //    //开始进行文件操作
            //    foreach (SourceDto sourceDto in sourceDtos)
            //    {
            //        string pathServer = System.IO.Path.Combine(rootpath, PasswordGenerate.PathDecode(sourceDto.SourcePath));
            //        //首先判断是否存在该GUID
            //        if (keyValuePairs_Source.ContainsKey(sourceDto.StrGuid))
            //        {

            //            string pathLocal = System.IO.Path.Combine(rootpath, keyValuePairs_Source[sourceDto.StrGuid]);
            //            //判断是否相等
            //            if (pathLocal == pathServer)
            //            {
            //                //如果不存在则创建，如果存在文件夹则保持原装
            //                if (!System.IO.Directory.Exists(pathLocal))
            //                {
            //                    System.IO.Directory.CreateDirectory(pathLocal);
            //                }
            //            }
            //            else  //如果本地路径地址和服务器地址是不一样的,则以服务器上面的文件路径为准
            //            {
            //                if (System.IO.Directory.Exists(pathLocal))
            //                {
            //                    System.IO.Directory.Move(pathLocal, pathServer);
            //                }
            //                //文件夹修改完成后，需要将字典中的所有的文件夹均修改过来
            //                foreach (KeyValuePair<string, string> keyValuePair in keyValuePairs_Source)
            //                {
            //                    //使用正则表达式搜索并替换文件夹
            //                    string strInput = keyValuePair.Value;
            //                    string pattern = keyValuePairs_Source[sourceDto.StrGuid];
            //                    string replacement = PasswordGenerate.PathDecode(sourceDto.SourcePath);
            //                    keyValuePairs_Source[keyValuePair.Key] = Regex.Replace(strInput, pattern, replacement);


            //                }
            //            }
            //        }
            //        else //若没有相关的文件夹，则新建。
            //        {
            //            //创建相应的文件夹
            //            Directory.CreateDirectory(pathServer);
            //            //将文件夹写入到字典中
            //            keyValuePairs_Source.Add(sourceDto.StrGuid, sourceDto.SourcePath);
            //        }

            //    }
            //    //文件夹部分修改完成，将文件夹信息更新到配置文件中,接下来更新文件部分
            //    ConfigService.DictToFile(keyValuePairs_Source, ConfigPath_Folder);
            //}

            ////下面进行文件文档的存储
            //var respone_doc = await httpClient.GetAsync("/api/file/request-documents/sss");
            //respone_doc.EnsureSuccessStatusCode();
            //var product_doc = await respone_doc.Content.ReadFromJsonAsync<ApiResult<List<DocumentDto>>>();
            //List<DocumentDto> documentDtos = product_doc.Data;
            //Dictionary<string, string> keyValuePairs_Docu = ConfigService.DictFromFile(ConfigPath_Docu);
            //if (keyValuePairs_Docu == null)//首次进行文件夹的初始化 
            //{
            //    keyValuePairs_Docu = new Dictionary<string, string>();
            //    foreach (DocumentDto documentDto in documentDtos)
            //    {
            //        string docuServer = System.IO.Path.Combine(rootpath, PasswordGenerate.PathDecode(documentDto.DocumentPath));
            //        //创建空的文件
            //        File.Create(docuServer);
            //        //将变量加入到字典种
            //        keyValuePairs_Docu.Add(documentDto.StrGuid, PasswordGenerate.PathDecode(documentDto.DocumentPath));

            //    }
            //    //将字典写入到配置文件种
            //    ConfigService.DictToFile(keyValuePairs_Docu, ConfigPath_Docu);
            //}
            //else//非第一次
            //{
            //    foreach (DocumentDto documentDto in documentDtos)
            //    {
            //        string docuServer = System.IO.Path.Combine(rootpath, PasswordGenerate.PathDecode(documentDto.DocumentPath));

            //        //如果本地文件已经存在，判断本地文件与服务器文件是否相等
            //        if (keyValuePairs_Docu.ContainsKey(documentDto.StrGuid))
            //        {
            //            string docuLocal = System.IO.Path.Combine(rootpath, keyValuePairs_Docu[documentDto.StrGuid]);
            //            if (docuLocal == docuServer)//两者是相等的 
            //            {
            //                if (!File.Exists(docuLocal))
            //                {
            //                    File.Create(docuLocal);
            //                }
            //            }
            //            else//若两者是不相等的，那么取服务器上的文件
            //            {
            //                File.Move(docuLocal, docuServer);
            //                //将更改存入到文件信息字典种
            //                keyValuePairs_Docu[documentDto.StrGuid] = documentDto.DocumentPath;
            //            }
            //        }
            //        else//若本地不存在该文件，则新建该文件
            //        {
            //            if (!File.Exists(docuServer))
            //            {
            //                File.Create(docuServer);  //创建相应的文件
            //            }
            //            //将文档的信息存储到文档字典当中
            //            keyValuePairs_Docu.Add(documentDto.StrGuid, documentDto.DocumentPath);
            //        }
            //    }
            //    //将整个文档字典存入到文件系统种
            //    ConfigService.DictToFile(keyValuePairs_Docu, ConfigPath_Docu);
            //}
            //***********************  上一版本的保存   ***********************************//
            string url = $"/api/file/init-file-tree";
            var respone = await httpClient.GetAsync(url);
            respone.EnsureSuccessStatusCode();
            var product = await respone.Content.ReadFromJsonAsync<ApiResult<bool>>();
            bool result = product.Data;

            if (result)
            {
                MessageBox.Show("成功");
            }

        }

        /// <summary>
        /// 将客户端的数据同步到服务器端，将当前用户所有的文件夹（权限为1）进行与服务器的更新，只是更新文件夹下面的文件 
        /// </summary>
        private async void SynchronizeToserverExcute()
        {
            //首先要拿到存储所有文件的路径
            string ConfigPath_FolderOwned = System.IO.Path.GetTempPath() + @"CRDCCollaboPlatConfig\Revit\FolderOwned.CRDC";

            //声明用户所拥有的文件夹中的文件资源；只能是文件资源  1：所有 2：所属
            List<DocumentDto> list_docuDtos = new List<DocumentDto>();
            Dictionary<string, string> keyValuePairs_fold = ConfigService.DictFromFile(ConfigPath_FolderOwned);
            //遍历字典，对文档进行赋值
            foreach(KeyValuePair<string,string> keyValuePair in keyValuePairs_fold)
            {
                string rootPath = ConfigurationManager.AppSettings["RootPath"];
                string folderPath = Path.Combine(rootPath, keyValuePair.Value);
                DirectoryInfo Thefolder = new DirectoryInfo(folderPath);
                //将所有文件的文件名称加入到文件列表中
                foreach(FileInfo fileInfo in Thefolder.GetFiles())
                {
                    DocumentDto documentDto = new DocumentDto();
                    documentDto.DocumentPath = fileInfo.FullName.Substring(rootPath.Length);
                    documentDto.DocumentName = fileInfo.Name;
                    list_docuDtos.Add(documentDto);
                }
            }

            //拿到用户的ID
            //将用户所有的文件都发到
            string Userid = ConfigService.GetSettingString("UserId").ToString();
            var response = await httpClient.PostAsJsonAsync<List<DocumentDto>>($"/api/file/synchronize-to-server-source/{Userid}", list_docuDtos);
            response.EnsureSuccessStatusCode();
            var products = await response.Content.ReadFromJsonAsync<ApiResult<Dictionary<string,string>>>();
            //拿到服务器端返回的键值对，并将拿到键值对放入到文档缓存中
            Dictionary<string, string> keyValuePairs = products.Data;
            if(keyValuePairs != null)   //首先判断拿到的值是否为NULL，如果不为NULL，则将拿到的键值对
            {
                string ConfigPath_Docu = System.IO.Path.GetTempPath() + @"CRDCCollaboPlatConfig\Revit\DocumentInfo.CRDC";

                Dictionary<string, string> kvp_New = ConfigService.DictFromFile(ConfigPath_Docu);
                foreach(var item in keyValuePairs)
                {
                    if (!kvp_New.ContainsKey(item.Key)) //若字典当中不存在某一个字典的键值，则进行合并
                    {
                        kvp_New.Add(item.Key, item.Value);
                    }
                }
                //将字典值写入到文档当中
                ConfigService.DictToFile(kvp_New, ConfigPath_Docu);

            }
        }

        /// <summary>
        /// 处理文件参数的命令的执行函数
        /// </summary>
        private async void HandleparaCommandExcute(object obj)
        {
            //拿到当前的选择的列表Item
            List<DataGridCellInfo> dataGridCellInfos = obj as List<DataGridCellInfo>;

            //拿到文件夹ROOT的长度
            int temp = ConfigurationManager.AppSettings["RootPath"].Length;
            //文件名称
            string fileName = dataGridCellInfos[0].Item.ToString().Substring(temp);
            fileName = PasswordGenerate.PathEncode(fileName);
            //拿到相关的用户配置信息
            string UserId = ConfigService.GetSettingString("UserId");
            string MajorID = ConfigService.GetSettingString("MajorID");
            //后期进行修改
            string datatype = "洞口";
            string description = "这个是一个测试的模型";
            string jsonstr = "22000";

            //构造网址路径
            string url = $"/api/file/json-data/{fileName}/{jsonstr}/{MajorID}/{datatype}/{description}";
            var respone = await httpClient.GetAsync(url);
            respone.EnsureSuccessStatusCode();
            var product = await respone.Content.ReadFromJsonAsync<ApiResult<string>>();
            string result = product.Data;
            if (result == "good")
            {
                MessageBox.Show("chengggo");
            }
        }


        /// <summary>
        /// 添加文件的引用，添加相应的文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void Command_Addfile(object sender, ExecutedRoutedEventArgs e)
        {
            string ConfigPath_Docu = System.IO.Path.GetTempPath() + @"CRDCCollaboPlatConfig\Revit\DocumentInfo.CRDC";


            int temp = ConfigurationManager.AppSettings["RootPath"].Length;
            string source = e.Parameter.ToString().Substring(temp);
            source = PasswordGenerate.PathEncode(source);
            MessageBox.Show(source);

            //拿到用户的配置参数
            string UserId = ConfigService.GetSettingString("UserId");

            string url = $"/api/file/check-user-source-auth/{UserId}/{source}";
            var respone = await httpClient.GetAsync($"/api/file/check-user-source-auth/{UserId}/{source}");
            respone.EnsureSuccessStatusCode();
            var product = await respone.Content.ReadFromJsonAsync<ApiResult<string>>();
            string authResult = product.Data;
            if (authResult == "1")//说明有权力增加页面
            {
                string newFile = System.IO.Path.Combine(e.Parameter.ToString(), "新增文件.rfa");
                string newFile_encode = PasswordGenerate.PathEncode(newFile);
                string url_newFile = $"/api/file/file/{UserId}/{newFile_encode}/{newFile_encode}";
                var respone_newFile = await httpClient.GetAsync(url_newFile);
                respone_newFile.EnsureSuccessStatusCode();
                var product_newFile = await respone_newFile.Content.ReadFromJsonAsync<ApiResult<DocumentDto>>();
                DocumentDto result = product_newFile.Data;
                if (result != null)//说明数据库端添加成功
                {
                    //拿到字典的键值对
                    Dictionary<string, string> keyValuePairs_Docu = ConfigService.DictFromFile(ConfigPath_Docu);
                    keyValuePairs_Docu.Add(result.StrGuid, PasswordGenerate.PathDecode(result.DocumentPath));
                    //存入本地数据库中
                    ConfigService.DictToFile(keyValuePairs_Docu, ConfigPath_Docu);
                    File.Create(newFile);


                }

            }



        }


    }
}
